package cn.xshi.log.client.handler;

import cn.xshi.log.client.annotation.OperationLogAnnotation;
import cn.xshi.log.client.request.RequestWrapper;
import cn.xshi.log.client.service.LogsUtil;
import cn.xshi.common.util.JsonUtil;
import cn.xshi.log.client.util.IDGenerate;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.util.CollectionUtils;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.HandlerMapping;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Map;

/**
 * @Desc 拦截器传输参数
 * @Author 邓纯杰
 * @CreateTime 2012-12-12 12:12:12
 */
@Slf4j
public class OpeationHandler implements HandlerInterceptor {

    @Resource
    LogsUtil logUtil;

    @Resource
    IDGenerate idGenerate;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws IOException {

        Map<String, String> params = null;

        HandlerMethod methodHandler =(HandlerMethod) handler;

        Boolean hasMethodAnnotation = methodHandler.hasMethodAnnotation(OperationLogAnnotation.class);//需要获取参数

        if(hasMethodAnnotation){//如果需要存储参数

            Long batch = idGenerate.nextId();

            String bodyParameterBody = getBodyParameterBody(request);

            Map<String, String[]> formDataParameterMap = request.getParameterMap();//form-data 参数集合

            Map<String, String> pathVars = (Map<String, String>) request.getAttribute(HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE);//Path作为参数获取
            try {
                if(!StringUtils.isEmpty(bodyParameterBody)){
                    logUtil.addOpLog(bodyParameterBody,batch);//传输body体参数
                }

            }catch (Exception e){
                log.error("操作Body体日志参数失败：{}.",e);
                return false;
            }

            try {
                if(!CollectionUtils.isEmpty(formDataParameterMap)){
                    logUtil.addOpLog(JsonUtil.toFastJson(formDataParameterMap),batch);//传输Form-data体参数
                }

            }catch (Exception e){
                log.error("操作Form-data体日志参数失败：{}.",e);
                return false;
            }

            try {
                if(!CollectionUtils.isEmpty(pathVars)){
                    logUtil.addOpLog(JsonUtil.toFastJson(pathVars),batch);//传输Path参数
                }
            }catch (Exception e){
                log.error("操作Path日志参数失败：{}.",e);
                return false;
            }
        }
        return true;
    }

    /**
     * 获取请求入参
     * @param request
     * @return
     */
    public static String getBodyParameterBody(HttpServletRequest request) {
        if(request instanceof RequestWrapper){
            RequestWrapper requestWrapper = (RequestWrapper) request;
            return requestWrapper.getRequestBody();
        }
        return null;
    }
}
